package JET.graphics;

import JET.Constants;
import JET.Centers.ControlCenter;
import JET.Scene;
import JET.graphics.jogl.JoglGraphicPanel;
import JET.mygui.MyGuiHelper;
import java.awt.Component;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import javax.swing.JScrollPane;

/**
 *
 * @author raos
 */
public class GraphicPanelHelper implements Constants{

    /**
     * Scales/zooms graphic panel view, by given steps.
     * The new scale is calculated by multiplying actual scale by
     * MOUSE_OTF_SCALE_GRAPHICPANEL_VIEW_PER_STEP constant multiplied by steps
     * argument - if steps ig greater than zero, otherwise actual scale is multiplied by
     * inversion of MOUSE_OTF_SCALE_GRAPHICPANEL_VIEW_PER_STEP multiplied by steps 
     * argument.
     * 
     * @param steps How much scale graphic panel
     * @param evt MouseEvent indicating ouse poition relative to screen and graphic panel
     *            (Note: yu can always get lastest occured mouse event object from
     *             ControlCenter.MouseCenter.mouseEvent public field).
     *
     * @param CC ControlCenter instance - it holds eferences to actual drawn
     *           GraphicPanel instance
     */
    public static void scaleGraphicPanel(GraphicPanel gp, int steps, MouseEvent evt, boolean precise, ControlCenter CC) {
        double newScale=0.0;
        double mulScale = precise ? MOUSE_OTF_SCALE_GRAPHICPANEL_VIEW_PER_STEP_PRECISE : MOUSE_OTF_SCALE_GRAPHICPANEL_VIEW_PER_STEP;
        Scene scene = CC.getScene(gp.getSceneName());

        switch (scene.GC.getGraphicMode()) {
            case Swing :
                // polozenie myszy na eranie tuz przed przeskalowaniem
                double monX = evt.getXOnScreen();
                double monY = evt.getYOnScreen();

                // ostatnie wartosci polozenia myszy w ukladzie silnika, przed przeskalowaniem
                double oldEx = gp.monitorToEngineX( monX );
                double oldEy = gp.monitorToEngineY( monY );

                // odswiezamy info w status bar'ze o polozeniu myszki w glownym oknie
                CC.GUIC.setMouseScreenPos(CC.MC.mouseEvent);
                CC.GUIC.setMouseEnginePos(CC.MC.mouseEvent);

                // liczymy wartosc nowej skali
                if ( steps < 0 ) newScale = gp.getViewScale() * mulScale;
                else if ( steps > 0 ) newScale = gp.getViewScale() / mulScale;

                // ograniczamy wartosc nowej skali do rzadanego przedzialu
                if ( newScale < GRAPHICPANEL_MINIMUM_SCALE ) newScale = GRAPHICPANEL_MINIMUM_SCALE;
                else if ( newScale > GRAPHICPANEL_MAXIMUM_SCALE ) newScale = GRAPHICPANEL_MAXIMUM_SCALE;

                // przeskalowanie graphic panel'u
                gp.setViewScale(newScale);
                CC.GUIC.setViewScaleLabel(newScale);
                gp.resizeToFitViewScale();

                // nowe wartosci polozenia myszy w ukladzie silnika, po przeskalowaniu
                double newEx = gp.monitorToEngineX(monX);
                double newEy = gp.monitorToEngineY(monY);

                // przeliczamy wspolrzedne z ukladu silnika do ukladu panelu graficznego
                double oldSx = gp.engineToScrX(oldEx);
                double oldSy = gp.engineToScrY(oldEy);
                double newSx = gp.engineToScrX(newEx);
                double newSy = gp.engineToScrY(newEy);

                // o ile przesunac viewport zeby myszka po przeskalowaniu wskazywala w ukladzie silnika (oldEx,oldEy)
                double dsx = newSx - oldSx;
                double dsy = newSy - oldSy;

                // dostajemy sie do viewportu scrollpanel'u i przesuwamy viewport tak aby
                // (oldEx,oldEy) oraz (newEx,newEy)lezaly w tym samym miejscu w ukladzie screen - czyli panelu graficznego :D
                JScrollPane sPane = MyGuiHelper.getFirstScrollPaneAncestor((Component)gp);
                Point viewportPos = sPane.getViewport().getViewPosition();
                Point newViewPos = new Point( (int)(viewportPos.getX()-dsx), (int)(viewportPos.getY()-dsy) );
                sPane.getViewport().setViewPosition( newViewPos );

                // Turning ON/OFF drawing help grid numbers
                double helpXDist = scene.GC.getGraphicPanel().getHelpGriddX() * scene.GC.getGraphicPanel().getViewScale();
                scene.GC.setDrawHelpGridXNumbers( helpXDist>50 );
                double helpYDist = scene.GC.getGraphicPanel().getHelpGriddY() * scene.GC.getGraphicPanel().getViewScale();
                scene.GC.setDrawHelpGridYNumbers( helpYDist>50 );
                break;
            case OpenGL :
                // odswiezamy info w status bar'ze o polozeniu myszki w glownym oknie
                CC.GUIC.setMouseScreenPos(CC.MC.mouseEvent);
                CC.GUIC.setMouseEnginePos(CC.MC.mouseEvent);

                // liczymy wartosc nowej skali

                if ( steps < 0 ) newScale = gp.getViewScale() * mulScale;
                else if ( steps > 0 ) newScale = gp.getViewScale() / mulScale;

                // ograniczamy wartosc nowej skali do rzadanego przedzialu
                if ( newScale < GRAPHICPANEL_MINIMUM_SCALE ) newScale = GRAPHICPANEL_MINIMUM_SCALE;
                else if ( newScale > GRAPHICPANEL_MAXIMUM_SCALE ) newScale = GRAPHICPANEL_MAXIMUM_SCALE;

                // last mouse position in scene system
                double oldSceneX = gp.scrToEngineX(evt.getX()),
                       oldSceneY = gp.scrToEngineY(evt.getY());

                // przeskalowanie graphic panel'u
                gp.setViewScale(newScale);
                CC.GUIC.setViewScaleLabel(newScale);

                double newSceneX = gp.scrToEngineX(evt.getX()),
                       newSceneY = gp.scrToEngineY(evt.getY());
                JoglGraphicPanel jgp = (JoglGraphicPanel)gp;
                jgp.viewX -= gp.engineToScrX(oldSceneX)-gp.engineToScrX(newSceneX);
                jgp.viewY += gp.engineToScrY(oldSceneY)-gp.engineToScrY(newSceneY);
                break;
        }
    }

}